package org.setec;

import org.setec.config.ConfigurationLoader;
import org.setec.config.InterpretableConfiguration;
import org.setec.utils.Utils;
import org.setec.utils.io.Persistance;

import java.lang.reflect.Method;

public class InlineMocker {

    private static InterpretableConfiguration configuration;

    public static InterpretableConfiguration getConfiguration() {
        return configuration;
    }

    public static void setConfiguration(InterpretableConfiguration interpretableConfiguration) {
        configuration = interpretableConfiguration;
    }

    public static void switchConfiguration(String path) {
        configuration = ConfigurationLoader.load(path);
    }

    public static Object inline(Object target, String methodName, Object... args) {

        Object result = null;

        Method method = null;
        try {
            method = target.getClass().getMethod(methodName, Utils.objectClasses(args));
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("No method " + methodName + " in class " +
                    target.getClass().toString() + "with args " + args);
        }


        String className = target.getClass().getName();

        if (getConfiguration().isProcessRealMethod(className, methodName, args)) {
            try {
                result = method.invoke(target, args);
                if (getConfiguration().isLearn(className, methodName, args)) {
                    Persistance.learn(getConfiguration().getStorage(), result, className, methodName, args);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            if (getConfiguration().isMock(className, methodName, args)) {
                result = Persistance.recall(getConfiguration().getStorage(), className, methodName, args);
            }
        }
        return result;
    }
}



